/**
 * Licensed under the Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0
 * @brief FreeRTOS应用示例
 * @details
 * @author 王炸物联网https://blog.csdn.net/wangyx1234?spm=1000.2115.3001.5343
 * @date 2022
 * @version 1.0
 * @copyright 版权所有，禁止用于商业用途
 */
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"

TaskHandle_t task1; // 任务1结构对象
TaskHandle_t task2;

static int task1_flag;           // 用于指示任务运行状态的标志变量
static int task2_flag;  

bool wait_event(void)
{
    return true;
}

void process_event(void)
{
    printf("suspend task1!\n");
    vTaskSuspend(NULL);
}

void notify(void)
{
    printf("task1 wakeup!\n");
}

/**
 * 任务的运行代码
 * @param param 任务初始运行参数
 */
static void task1_process(void *arg)
{
    static const char *TASK1_TAG = "TASK1";
    while (1) {
        if(wait_event()) {
            process_event();
            notify();
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

static void task2_process(void *arg)
{
    static const char *TASK2_TAG = "TASK2";
    int cnt = 0;
    while (1) {
        ESP_LOGI(TASK2_TAG, "task2_flag = %d, arg2 = %s", task2_flag, (char *)arg);
        task2_flag++;
        vTaskDelay(pdMS_TO_TICKS(500));
        ESP_LOGI(TASK2_TAG, "task2_flag = %d, cnt= %d", task2_flag, cnt++);
        vTaskDelay(pdMS_TO_TICKS(500));
        ESP_LOGI(TASK2_TAG, "task2_flag = %d, cnt= %d", task2_flag, cnt++);
        vTaskDelay(pdMS_TO_TICKS(500));
        ESP_LOGI(TASK2_TAG, "task2_flag = %d, cnt= %d", task2_flag, cnt++);
        cnt = 0;
    }
}

static void init(void) {
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
            CONFIG_IDF_TARGET,
            chip_info.cores,
            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}

void app_main(void)
{
    init();
    /*
    static BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *constpcName, const uint32_t usStackDepth, 
    void *constpvParameters, UBaseType_t uxPriority, TaskHandle_t *constpxCreatedTask)*/
    xTaskCreate(&task1_process, "task1", 1024*2, (void *)"1", configMAX_PRIORITIES, &task1); // configMAX_PRIORITIES = 25
    xTaskCreatePinnedToCore(&task2_process, "task2", 1024*2, (void *)"2", configMAX_PRIORITIES-2, &task2, 0);
    // Use the handle to suspend the task.
    if(task2 != NULL) {
        vTaskSuspend(task2);
        printf("Suspend task2!\n");
    }

    for (int i = 3; i >= 0; i--) {
        printf("Resume in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

    vTaskResume(task2);
    vTaskResume(task1);

    vTaskDelay(1000 / portTICK_PERIOD_MS);
    vTaskSuspend(task1);
    vTaskSuspend(task2);
}
